Skip to content

Match Apache Maven's anonymous-first authentication for POM and JAR downloads#8169

Open
Jammy-Louie wants to merge 6 commits into
mainfrom
maven-anonymous-first-auth
Open

Match Apache Maven's anonymous-first authentication for POM and JAR downloads#8169
Jammy-Louie wants to merge 6 commits into
mainfrom
maven-anonymous-first-auth

Conversation

@Jammy-Louie

@Jammy-Louie Jammy-Louie commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  1. Anonymous-first requests. MavenPomDownloader (reachability probes, jar-existence HEAD, and body/metadata GETs) and MavenArtifactDownloader now request without credentials first and retry with credentials on a credential-rejecting 4xx. This also stops sending credentials to repositories that serve anonymously.
  2. Per-host auth cache. A session-scoped host:port set on the ExecutionContext records which endpoints required authentication, mirroring Maven Resolver's BasicAuthCache (and the existing getUnreachableEndpoints pattern). Once a host is known to require auth, both downloaders authenticate preemptively. MavenArtifactDownloader gains additive ExecutionContext constructors, and JavaRewriteRpc passes its context through so the jar phase shares the cache warmed during POM resolution.

The first request to a private host costs one extra anonymous 401 probe before authenticating; the cache limits this to once per host per session, the same one-time cost Maven pays.

Test plan

  • MavenPomDownloaderTest#doesNotSendCredentialsWhenRepositoryServesAnonymously
  • MavenPomDownloaderTest#authenticatesPreemptivelyAfterCredentialsRequired
  • MavenArtifactDownloaderTest#retriesWithCredentialsWhenAnonymousReturns401, #retriesWithHttpHeaderAuthWhenAnonymousReturns401
  • MavenArtifactDownloaderTest#doesNotFallBackToAnonymousOnTransientClientError
  • MavenArtifactDownloaderTest#authenticatesPreemptivelyAfterFirstChallengeForSameHost
  • Full rewrite-maven module test suite

Mirror Apache Maven Resolver's DeferredCredentialsProvider: issue POM,
metadata, reachability, jar-existence, and artifact requests without
credentials, and send Basic auth only once the server challenges an
anonymous request with a 4xx. Both downloaders previously applied
credentials preemptively, leaking them to repositories that serve
anonymously.

Split out applyTimeoutToRequest so anonymous requests keep their
timeouts without sending configured headers or credentials.
…robes

Add a session-scoped MavenAuthenticationCache on the ExecutionContext that
records repository endpoints (host:port) which challenged an anonymous
request. Once a host is known to require credentials, both
MavenPomDownloader and MavenArtifactDownloader authenticate preemptively
rather than paying another anonymous 401 round-trip, mirroring Apache Maven
Resolver's per-session BasicAuthCache.

MavenArtifactDownloader now accepts an ExecutionContext (additive
constructors; existing ones default to a per-instance context) so the JAR
phase shares the cache populated during POM resolution. JavaRewriteRpc
passes its context through.
@github-project-automation github-project-automation Bot moved this to In Progress in OpenRewrite Jul 3, 2026
@Jammy-Louie Jammy-Louie marked this pull request as ready for review July 6, 2026 18:45
Match the codebase convention where ExecutionContext is the trailing
argument on most multi-arg method signatures.
@timtebeek timtebeek added enhancement New feature or request maven labels Jul 9, 2026

@timtebeek timtebeek left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple guiding questions; nothing that can't be fixed I think. Let me know your thoughts and happy to work this in if you agree.

Address PR review feedback: fold the anonymous-first authentication cache
into MavenExecutionContextView alongside getUnreachableEndpoints(), so the
two endpoint-tracking behaviors live side by side instead of in a separate
MavenAuthenticationCache class. Also consult the cache in jarExistsForPomUri
so the JAR-existence HEAD probe authenticates preemptively for hosts already
known to require credentials.
@timtebeek timtebeek force-pushed the maven-anonymous-first-auth branch from 139268d to 7218621 Compare July 10, 2026 16:39
The constructors that don't accept an ExecutionContext fall back to a
throwaway InMemoryExecutionContext, so the anonymous-first authentication
cache cannot be shared with POM/metadata resolution. Deprecate them in favor
of the ExecutionContext-accepting overloads and migrate the in-tree test
callers accordingly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request maven

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

2 participants